package com.takwolf.libgdx.graphics;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class SpriteSheet extends Sprite {

    private Animation animation;
    private TextureRegion currentFrame;
    private int currentFrameIndex;
    private boolean isFinished;

    public SpriteSheet(float frameDuration, TextureRegion region, int tileWidth, int tileHeight, Animation.PlayMode playMode) {
        TextureRegion[][] temp = region.split(tileWidth, tileHeight);
        TextureRegion[] frames = new TextureRegion[temp.length * temp[0].length];
        for (int i = 0; i < temp.length; i++) {
            System.arraycopy(temp[i], 0, frames, i * temp[i].length, temp[i].length);
        }
        animation = new Animation(frameDuration, frames);
        animation.setPlayMode(playMode);
        currentFrame = animation.getKeyFrame(0);
        setRegion(currentFrame);
        setSize(currentFrame.getRegionWidth(), currentFrame.getRegionHeight());
        setOrigin(currentFrame.getRegionWidth() / 2, currentFrame.getRegionHeight() / 2);
        currentFrameIndex = animation.getKeyFrameIndex(0);
        isFinished = animation.isAnimationFinished(0);
    }

    public SpriteSheet(float frameDuration, TextureRegion region, int tileWidth, int tileHeight) {
        this(frameDuration, region, tileWidth, tileHeight, Animation.PlayMode.NORMAL);
    }

    public SpriteSheet(float frameDuration, Texture texture, int tileWidth, int tileHeight, Animation.PlayMode playMode) {
        this(frameDuration, new TextureRegion(texture), tileWidth, tileHeight, playMode);
    }

    public SpriteSheet(float frameDuration, Texture texture, int tileWidth, int tileHeight) {
        this(frameDuration, texture, tileWidth, tileHeight, Animation.PlayMode.NORMAL);
    }

    public static SpriteSheet create(float frameDuration, TextureRegion region, int frameCols, int frameRows, Animation.PlayMode playMode) {
        return new SpriteSheet(frameDuration, region, region.getRegionWidth() / frameCols, region.getRegionHeight() / frameRows, playMode);
    }

    public static SpriteSheet create(float frameDuration, TextureRegion region, int frameCols, int frameRows) {
        return create(frameDuration, region, frameCols, frameRows, Animation.PlayMode.NORMAL);
    }

    public static SpriteSheet create(float frameDuration, Texture texture, int frameCols, int frameRows, Animation.PlayMode playMode) {
        return new SpriteSheet(frameDuration, texture, texture.getWidth() / frameCols, texture.getHeight() / frameRows, playMode);
    }

    public static SpriteSheet create(float frameDuration, Texture texture, int frameCols, int frameRows) {
        return create(frameDuration, texture, frameCols, frameRows, Animation.PlayMode.NORMAL);
    }

    public void update(float stateTime) {
        currentFrame = animation.getKeyFrame(stateTime);
        setRegion(currentFrame);
        currentFrameIndex = animation.getKeyFrameIndex(stateTime);
        isFinished = animation.isAnimationFinished(stateTime);
    }

    public TextureRegion getCurrentFrame() {
        return currentFrame;
    }

    public int getCurrentFrameIndex() {
        return currentFrameIndex;
    }

    public Animation.PlayMode getPlayMode() {
        return animation.getPlayMode();
    }

    public void setPlayMode(Animation.PlayMode playMode) {
        animation.setPlayMode(playMode);
    }

    public void setFrameDuration(float frameDuration) {
        animation.setFrameDuration(frameDuration);
    }

    public float getFrameDuration() {
        return animation.getFrameDuration();
    }

    public float getAnimationDuration() {
        return animation.getAnimationDuration();
    }

    public boolean isAnimationFinished() {
        return isFinished;
    }

    public TextureRegion getKeyFrame(float stateTime, boolean looping) {
        return animation.getKeyFrame(stateTime, looping);
    }

    public TextureRegion getKeyFrame(float stateTime) {
        return animation.getKeyFrame(stateTime);
    }

    public int getKeyFrameIndex(float stateTime) {
        return animation.getKeyFrameIndex(stateTime);
    }

}
